use core::{Package, VirtualManifest, EitherManifest, SourceId};
use core::{PackageIdSpec, Dependency};
use ops;
-use util::{Config, CargoResult};
+use util::{Config, CargoResult, Filesystem};
use util::paths;
/// The core abstraction in Cargo for working with a workspace of crates.
// `current_manifest` was found on the filesystem with `[workspace]`.
root_manifest: Option<PathBuf>,
+ // Allows to override the target directory for the purposes of `cargo install`.
+ target_dir: Option<Filesystem>,
+
// List of members in this workspace with a listing of all their manifest
// paths. The packages themselves can be looked up through the `packages`
// set above.
packages: HashMap::new(),
},
root_manifest: None,
+ target_dir: None,
members: Vec::new(),
};
ws.root_manifest = try!(ws.find_root(manifest_path));
///
/// This is currently only used in niche situations like `cargo install` or
/// `cargo package`.
- pub fn one(package: Package, config: &'cfg Config) -> Workspace<'cfg> {
+ pub fn one(package: Package, config: &'cfg Config, target_dir: Option<Filesystem>) -> Workspace<'cfg> {
let mut ws = Workspace {
config: config,
current_manifest: package.manifest_path().to_path_buf(),
packages: HashMap::new(),
},
root_manifest: None,
+ target_dir: target_dir,
members: Vec::new(),
};
{
}.parent().unwrap()
}
+ pub fn target_dir(&self) -> Filesystem {
+ if let Some(ref fs) = self.target_dir {
+ return fs.clone()
+ }
+ if let Some(fs) = self.config.target_dir() {
+ return fs.clone()
+ }
+ Filesystem::new(self.root().join("target"))
+ }
+
/// Returns the root [replace] section of this workspace.
///
/// This may be from a virtual crate or an actual crate.
/// Cleans the project from build artifacts.
pub fn clean(ws: &Workspace, opts: &CleanOptions) -> CargoResult<()> {
- let target_dir = opts.config.target_dir(&ws);
+ let target_dir = ws.target_dir();
// If we have a spec, then we need to delete some packages, otherwise, just
// remove the whole target directory and be done with it!
// Don't bother locking here as if this is getting deleted there's
// nothing we can do about it and otherwise if it's getting overwritten
// then that's also ok!
- let target_dir = options.compile_opts.config.target_dir(ws);
+ let target_dir = ws.target_dir();
let path = target_dir.join("doc").join(&name).join("index.html");
let path = path.into_path_unlocked();
if fs::metadata(&path).is_ok() {
crates.io, or use --path or --git to \
specify alternate source"))))
};
- let ws = Workspace::one(pkg, config);
+
+
+ let mut td_opt = None;
+ let overidden_target_dir = if source_id.is_path() {
+ None
+ } else if let Ok(td) = TempDir::new("cargo-install") {
+ let p = td.path().to_owned();
+ td_opt = Some(td);
+ Some(Filesystem::new(p))
+ } else {
+ Some(Filesystem::new(config.cwd().join("target-install")))
+ };
+
+ let ws = Workspace::one(pkg, config, overidden_target_dir);
let pkg = try!(ws.current());
// Preflight checks to check up front whether we'll overwrite something.
try!(check_overwrites(&dst, pkg, &opts.filter, &list, force));
}
- let mut td_opt = None;
- let target_dir = if source_id.is_path() {
- config.target_dir(&ws)
- } else {
- if let Ok(td) = TempDir::new("cargo-install") {
- let p = td.path().to_owned();
- td_opt = Some(td);
- Filesystem::new(p)
- } else {
- Filesystem::new(config.cwd().join("target-install"))
- }
- };
- config.set_target_dir(target_dir.clone());
let compile = try!(ops::compile_ws(&ws, Some(source), opts).chain_error(|| {
if let Some(td) = td_opt.take() {
// preserve the temporary directory, so the user can inspect it
}
human(format!("failed to compile `{}`, intermediate artifacts can be \
- found at `{}`", pkg, target_dir.display()))
+ found at `{}`", pkg, ws.target_dir().display()))
}));
let binaries: Vec<(&str, &Path)> = try!(compile.binaries.iter().map(|bin| {
let name = bin.file_name().unwrap();
if !source_id.is_path() {
// Don't bother grabbing a lock as we're going to blow it all away
// anyway.
- let target_dir = target_dir.into_path_unlocked();
+ let target_dir = ws.target_dir().into_path_unlocked();
try!(fs::remove_dir_all(&target_dir));
}
}
let filename = format!("{}-{}.crate", pkg.name(), pkg.version());
- let dir = config.target_dir(ws).join("package");
+ let dir = ws.target_dir().join("package");
let mut dst = {
let tmp = format!(".{}", filename);
try!(dir.open_rw(&tmp, config, "package scratch space"))
let new_pkg = Package::new(new_manifest, &manifest_path);
// Now that we've rewritten all our path dependencies, compile it!
- let ws = Workspace::one(new_pkg, config);
+ let ws = Workspace::one(new_pkg, config, None);
try!(ops::compile_ws(&ws, None, &ops::CompileOptions {
config: config,
jobs: opts.jobs,
pub fn new(ws: &Workspace,
triple: Option<&str>,
dest: &str) -> CargoResult<Layout> {
- let mut path = ws.config().target_dir(ws);
+ let mut path = ws.target_dir();
// Flexible target specifications often point at filenames, so interpret
// the target triple as a Path and then just use the file stem as the
// component for the directory name.
use rustc_serialize::{Encodable,Encoder};
use toml;
use core::shell::{Verbosity, ColorConfig};
-use core::{MultiShell, Workspace};
+use core::MultiShell;
use util::{CargoResult, CargoError, ChainError, Rustc, internal, human};
use util::{Filesystem, LazyCell};
values: LazyCell<HashMap<String, ConfigValue>>,
cwd: PathBuf,
rustdoc: LazyCell<PathBuf>,
- target_dir: RefCell<Option<Filesystem>>,
+ target_dir: Option<Filesystem>,
extra_verbose: Cell<bool>,
frozen: Cell<bool>,
locked: Cell<bool>,
cwd: cwd,
values: LazyCell::new(),
rustdoc: LazyCell::new(),
- target_dir: RefCell::new(None),
+ target_dir: None,
extra_verbose: Cell::new(false),
frozen: Cell::new(false),
locked: Cell::new(false),
pub fn cwd(&self) -> &Path { &self.cwd }
- pub fn target_dir(&self, ws: &Workspace) -> Filesystem {
- self.target_dir.borrow().clone().unwrap_or_else(|| {
- Filesystem::new(ws.root().join("target"))
- })
- }
-
- pub fn set_target_dir(&self, path: Filesystem) {
- *self.target_dir.borrow_mut() = Some(path);
+ pub fn target_dir(&self) -> Option<&Filesystem> {
+ self.target_dir.as_ref()
}
fn get(&self, key: &str) -> CargoResult<Option<ConfigValue>> {
fn scrape_target_dir_config(&mut self) -> CargoResult<()> {
if let Some(dir) = env::var_os("CARGO_TARGET_DIR") {
- *self.target_dir.borrow_mut() = Some(Filesystem::new(self.cwd.join(dir)));
+ self.target_dir = Some(Filesystem::new(self.cwd.join(dir)));
} else if let Some(val) = try!(self.get_path("build.target-dir")) {
let val = self.cwd.join(val.val);
- *self.target_dir.borrow_mut() = Some(Filesystem::new(val));
+ self.target_dir = Some(Filesystem::new(val));
}
Ok(())
}